package com.tanhua.dubbo.server.service;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.alibaba.dubbo.config.annotation.Reference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tanhua.common.enums.SexEnum;
import com.tanhua.common.exception.BusinessException;
import com.tanhua.common.mapper.UserInfoMapper;
import com.tanhua.common.pojo.*;
import com.tanhua.common.utils.UserThreadLocal;
import com.tanhua.common.vo.ErrorResult;
import com.tanhua.dubbo.server.api.HuanXinApi;
import com.tanhua.dubbo.server.api.UserLikeApi;
import com.tanhua.dubbo.server.api.VisitorsApi;
import com.tanhua.common.pojo.BlackList;
import com.tanhua.dubbo.server.config.XiaoSiConfig;
import com.tanhua.dubbo.server.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * Created with IntelliJ IDEA.
 *
 * @ClassName: MyCenterService
 * @Author:王晨晗
 * @Description:
 * @Date: 2022/01/05/19:33
 */
@Service
@Slf4j
public class MyCenterService {
    @Autowired
    private UserInfoMapper userInfoMapper;

    @Reference
    private UserLikeApi userLikeApi;

    @Autowired
    private UserInfoService userInfoService;

    @Reference
    private VisitorsApi visitorsApi;

    @Autowired
    private SettingsService settingsService;

    @Autowired
    private QuestionService questionService;

    @Autowired
    private BlackListService blackListService;

    @Autowired
    private XiaoSiConfig xiaoSiConfig;

    @Reference
    private HuanXinApi huanXinApi;

    /**
     * @description 根据用户id查询用户详细信息
     * @param userId  当前用户id
     * @return
     */
    public UserInfoVo queryUserInfoByUserId(Long userId) {
        //获取当前用户信息
        User user = UserThreadLocal.get();
        //根据用户id查询到用户的详细信息
        UserInfo userInfo = userInfoService.queryUserInfoByUserId(user.getId());
        //判断用户信息对象是否为空
        if (ObjectUtil.isEmpty(userInfo)){
            //为空,返回null
            return null;
        }
        //封装用户详细信息,排除婚姻属性
        UserInfoVo userInfoVo = BeanUtil.copyProperties(userInfo, UserInfoVo.class , "marriage");
        //封装用户性别
        userInfoVo.setGender(userInfo.getSex().getValue() == 1 ? "man" : "woman");
        //封装用户婚姻状况
        userInfoVo.setMarriage(StrUtil.equals("已婚",userInfo.getMarriage()) ? 1 : 0);
        //返回响应结果
        return userInfoVo;
    }

    /**
     * @description 修改用户信息
     * @param userInfoVo  用户详细信息响应对象
     * @return
     */
    public void updateUserInfo(UserInfoVo userInfoVo) {
        //获取user信息
        User user = UserThreadLocal.get();
        //封装userinfo信息
        UserInfo userInfo = new UserInfo();
        userInfo.setUserId(user.getId());       //用户id
        userInfo.setAge(Integer.valueOf(userInfoVo.getAge()));      //年龄
        userInfo.setNickName(userInfoVo.getNickname());     //昵称
        userInfo.setSex(StringUtils.equalsIgnoreCase(userInfoVo.getGender() , "man") ? SexEnum.MAN : SexEnum.WOMAN);       //性别
        userInfo.setBirthday(userInfoVo.getCity()); //出生日期
        userInfo.setCity(userInfoVo.getCity());    //城市
        userInfo.setEdu(userInfoVo.getEducation());     //学历
        userInfo.setIncome(StringUtils.replaceAll(userInfoVo.getIncome() , "K" , ""));     //收入
        userInfo.setIndustry(userInfoVo.getProfession());   //行业
        userInfo.setMarriage(userInfoVo.getMarriage() == 1?"已婚" : "未婚");        //婚姻
        //根据用户id更新用户信息
        Boolean result = userInfoService.updateUserInfoByUserId(userInfo);
        //判断更新结果
        if (!result){
            throw new BusinessException(ErrorResult.updateUserInfoError());       //更新用户失败
        }
    }

    /**
     * @description 查询用户的相互关注,喜欢,粉丝
     * @return
     */
    public CountsVo queryCounts() {
        //获取用户对象
        User user = UserThreadLocal.get();
        //封装相互关注,喜欢,粉丝的响应数据
        CountsVo countsVo = new CountsVo();
        countsVo.setEachLoveCount(userLikeApi.queryEachLikeCount(user.getId()));    //相互喜欢数
        countsVo.setFanCount(userLikeApi.queryFanCount(user.getId()));      //粉丝数
        countsVo.setLoveCount(userLikeApi.queryLoveCount(user.getId()));  //喜欢数
        //返回查询统计Vo实体对象
        return countsVo;
    }

    /**
     * @description 查询喜欢,谁看过我/粉丝/相互喜欢列表
     * @param type      类型
     * @param page      当前页
     * @param pageSize  每页条数
     * @return
     */
    public PageResult queryFriendList(Integer type, Integer page, Integer pageSize , String nickName) {
        page = page == 0 ? 1: page;     //保证page不为0;
        //获取user信息;
        User user = UserThreadLocal.get();
        //创建推荐用户的空集合 ,主要封装用户id和缘分值
        List<RecommendUser> recommendUsers = Collections.emptyList();
        //判断type ,确定执行何种操作
        switch (type){
            case 1:     //相互喜欢
                recommendUsers = userLikeApi.queryEachLikeList(user.getId(), page, pageSize , nickName);
                break;
            case 2:     //我关注
                recommendUsers = userLikeApi.queryLoveList(user.getId() , page , pageSize, nickName);
                break;
            case 3:     //粉丝
                recommendUsers = userLikeApi.queryFanList(user.getId() , page , pageSize, nickName);
                break;
            case 4:     //访客列表
                recommendUsers = visitorsApi.queryVisitorList(user.getId(), page, pageSize, nickName);
                break;
        }
        //执行封装响应FriendVo对象集合的方法
        List<FriendVo> list = fillFriendVoList(recommendUsers , nickName);
        //创建pageResult对象;
        PageResult pageResult = new PageResult();
        //封装数据
        pageResult.setPage(page);   //当前页
        pageResult.setPagesize(pageSize);   //每页条数
        pageResult.setItems(list);      //数据集合
        //响应结果
        return pageResult;
    }

    /**
     * @description 封装FriendVo对象
     * @param recommendUserList 推荐用户集合
     * @return
     */
    public List<FriendVo> fillFriendVoList(List<RecommendUser> recommendUserList , String nickName){
        //为空 返回空集合
        if(CollUtil.isEmpty(recommendUserList)){
            return Collections.emptyList();   //返回空集合
        }

        //获取访客记录的访问者id
        List<Object> userIds = CollUtil.getFieldValues(recommendUserList, "userId");
        //查询数据库 获取用户详细信息
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        //构建条件 用户id处于指定id集合中
        wrapper.in("user_id" , userIds );
        //判断昵称是否为空
        if (StrUtil.isNotEmpty(nickName)){
            //昵称不为空, 添加模糊查询条件
            wrapper.like("nick_name" , nickName);
        }
        //执行查询,获取用户详细信息集合
        List<UserInfo> userInfoList = userInfoMapper.selectList(wrapper);
        //遍历访客集合,封装响应数据
        List<FriendVo> friendVoList = new ArrayList<>();
        //遍历推荐用户集合
        for (RecommendUser recommendUser : recommendUserList) {
            //遍历用户详细信息集合
            for (UserInfo userInfo : userInfoList) {
                //比较id一致,即找到对应用户的详细信息;
                if (ObjectUtil.equals(recommendUser.getUserId(), userInfo.getUserId())) {
                    //封装响应的列表对象;
                    FriendVo friendVo = new FriendVo();
                    friendVo.setAge(userInfo.getAge());     //年龄
                    friendVo.setAvatar(userInfo.getLogo());     //头像
                    friendVo.setGender(userInfo.getSex().name().toLowerCase());     //性别
                    friendVo.setId(userInfo.getUserId());       //用户id
                    friendVo.setNickname(userInfo.getNickName());       //昵称
                    friendVo.setMatchRate(recommendUser.getScore().intValue());       //匹配度
                    friendVo.setEducation(userInfo.getEdu());       //学历
                    friendVo.setCity(userInfo.getCity());       //城市
                    friendVo.setMarriage(StrUtil.equals(userInfo.getMarriage() , "已婚") ? 1:0);      //婚姻状态
                    friendVo.setAlreadyLove(userLikeApi.isLike(recommendUser.getToUserId() , userInfo.getUserId()));       //是否喜欢
                    //添加friendvo到集合中
                    friendVoList.add(friendVo);
                    //结束循环;
                    break;
                }
            }
        }
        //返回封装好的响应列表对象;
        return friendVoList;
    }

    /**
     * @description 取消喜欢
     * @param userId  用户id;
     * @return
     */
    public void disLike(Long userId) {
        //获取用户信息;
        User user = UserThreadLocal.get();
        //调用取消喜欢方法
        userLikeApi.notLikeUser(user.getId() , userId);
    }

    /**
     * @description 喜欢粉丝
     * @param userId
     * @return
     */
    public void likeFan(Long userId) {
        //获取user信息;
        User user = UserThreadLocal.get();
        //调用喜欢方法
        userLikeApi.likeUser(user.getId() , userId);
    }

    /**
     * @description 查看用户通用配置
     * @return
     */
    public SettingsVo querySettings() {
        //获取用户信息
        User user = UserThreadLocal.get();
        //创建设置响应对象;
        SettingsVo settingsVo = new SettingsVo();
        settingsVo.setId(user.getId());     //用户id
        settingsVo.setPhone(user.getMobile());  //获取手机号
        //查询用户的设置
        Settings settings = settingsService.querySettings(user.getId());
        //判断是否为空 不为空则更改设置,为空则使用默认设置
        if (null != settings){
            settingsVo.setGonggaoNotification(settings.getGonggaoNotification());   //用户公告通知
            settingsVo.setPinglunNotification(settings.getPinglunNotification());   //用户评论通知
            settingsVo.setLikeNotification(settings.getLikeNotification());         //用户喜欢通知
        }
        //查询陌生人问题
        Question question = questionService.queryQuestion(user.getId());
        //判断陌生人问题是否为空
        if (question != null){
            settingsVo.setStrangerQuestion(question.getTxt());      //不为空,填充问题
        }else{
            //为空, 分配默认问题
            settingsVo.setStrangerQuestion("你喜欢什么颜色?");
        }
        //返回结果
        return settingsVo;
    }

    /**
     * @description 保存我的陌生人问题
     * @param content   陌生人问题
     * @return
     */
    public void saveQuestions(String content) {
        //获取user信息;
        User user = UserThreadLocal.get();
        //执行保存陌生人问题 方法;
        questionService.saveQuestions(user.getId() , content);
    }

    /**
     * @description 保存用户通知设置
     * @param settings  用户通知设置
     * @return
     */
    public void saveNotifications(Settings settings) {
        //获取user信息
        User user = UserThreadLocal.get();
        //封装设置用户的id
        settings.setUserId(user.getId());
        //执行通知设置更新操作
        settingsService.updateSettings(settings);
    }

    /**
     * @description 查询黑名单列表
     * @param page  当前页
     * @param pageSize 每页条数
     * @return
     */
    public PageResult queryBlackList(Integer page, Integer pageSize) {
        //获取用户信息
        User user = UserThreadLocal.get();
        //查询数据库 , 获取黑名单列表
        List<BlackList> blackLists = blackListService.queryBlackList(user.getId(), page, pageSize);
        //封装pageResult对象
        PageResult pageResult = new PageResult();
        pageResult.setPage(page);       //当前页
        pageResult.setPagesize(pageSize);       //每页显示条数
        //判断集合是否为空
        if (CollUtil.isEmpty(blackLists)){
            return pageResult;  //为空,返回数据
        }
        //不为空,封装响应对象集合
        //获取黑名单集合中用户id
        List<Object> userId = CollUtil.getFieldValues(blackLists, "blackUserId");
        //查询用户详细信息表,获取用户详细信息
        QueryWrapper<UserInfo> wrapper = new QueryWrapper<>();
        //构建查询条件
        wrapper.in("user_id" , userId);
        //执行查询
        List<UserInfo> userInfoList = userInfoService.queryUserInfoList(wrapper);
        //创建响应数据的集合
        List<BlackListVo> blackListVos = new ArrayList<>();
        //封装获取得到的集合
        for (UserInfo userInfo : userInfoList) {
            //创建黑名单响应数据
            BlackListVo blackListVo = new BlackListVo();
            blackListVo.setId(userInfo.getUserId());    //用户id
            blackListVo.setNickname(userInfo.getNickName());    //昵称
            blackListVo.setAvatar(userInfo.getLogo());  //头像
            blackListVo.setAge(userInfo.getAge());      //年龄
            blackListVo.setGender(userInfo.getSex().name().toLowerCase());    //性别
            //添加到集合
            blackListVos.add(blackListVo);
        }
        //封装集合
        pageResult.setItems(blackListVos);          //结果集合
        pageResult.setCounts(blackLists.size());        //总记录数
        //返回结果集
        return pageResult;
    }

    /**
     * @description 移除黑名单
     * @param userId
     * @return
     */
    public void removeBlackList(Long userId) {
        //获取用户信息
        User user = UserThreadLocal.get();
        //执行删除黑名单
        Boolean result = blackListService.removeBlackList(user.getId(), userId);
        //判断是否删除成功, 删除失败抛出异常
        if (!result){
            throw new BusinessException(ErrorResult.removeBlackListError());       // 移除黑名单失败
        }else {
            //移除环信中的黑名单
            result = huanXinApi.removeBlackUser(user.getId(), userId);
            //判断环信是否移除成功
            if (!result){
                throw new BusinessException(ErrorResult.huanxinRemoveBlackError());   //环信移除黑名单信息失败
            }
        }
    }

    /**
     * @description 客服咨询
     * @param content  咨询内容
     * @return
     */
    public String consultOnline(String content) {
        //创建map集合 封装请求参数
        Map<String , String> param = new HashMap<>();
        param.put("appid" , xiaoSiConfig.getAppId());       //应用id
        param.put("userid" , xiaoSiConfig.getUserId());     //用户id 用于上下文对话
        param.put("spoken" , content);      //对话内容
        //设置请求方式和url路径
        HttpRequest httpRequest = HttpRequest.post(xiaoSiConfig.getUrl());
        //添加请求参数
        httpRequest.body(JSONUtil.toJsonStr(param));
        //执行请求,获取响应消息
        HttpResponse response = httpRequest.execute();
        //获取body内容
        String body = response.body();
        //解析body
        JSONObject jsonObject = JSONUtil.parseObj(body);
        //获取响应状态
        String message = jsonObject.getStr("message");
        String text;  //客服机器人的回复内容
        //判断响应是否成功
        if (StrUtil.equals("success" , message)){
            //响应成功,获取响应的文本内容
            Object data = jsonObject.getObj("data");            // data对象,包含info和type属性
            Object info = JSONUtil.parseObj(data).getObj("info");   //info对象 ,包含响应的正文内容
            text = JSONUtil.parseObj(info).getStr("text");   //响应的正文
        }else {
            //响应失败,回复"客服正忙,请稍等"
            text = "客服正忙,请稍等";
            //写入日志
            log.error("客服机器人无法响应~");
        }
        //返回响应数据
        return text;
    }

    /**
     * @description 添加黑名单
     * @param userId 用户id
     * @return
     */
    public void addBlackList(Long userId) {
        //获取user
        User user = UserThreadLocal.get();
        //保存黑名单信息到数据库
        Boolean result = blackListService.addBlackList(user.getId(), userId);
        //判断是否添加成功
        if (result){
            //注册黑名单关系到环信
            result = huanXinApi.addBlackUser(user.getId(), userId);
            //判断环信是否添加成功
            if (!result){
                throw new BusinessException(ErrorResult.huanxinAddBlackError());   //环信添加黑名单信息失败
            }
        }else{
            throw new BusinessException(ErrorResult.addBlackUserError()); // 数据库添加黑名单关系失败
        }
    }
}
